2장 의미있는 이름
Intro
나는 평소에 네이밍을 하는데 어려움이 있었다. 여러 컨벤션들이 있었지만, 내가 옆에 두고 하지 않는 이상 좋은 네이밍을 하기엔 어려웠다. 아직은 경험이 없고 익숙하지 않아서 일까?… 그래서 더더욱 이번 챕터를 재미있게 봤다.
의도를 분명히 밝혀라
"의도가 분명하게 이름을 지으라"따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 말이다.
int d; // 경과 시간(단위: 날짜)여기서 d는 아무 의미도 드러나지 않는다.
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워진다. 그러면서도 영어 동사의 표현을 잘 알아야겠다는 생각이 든다.
다음 코드가 무엇을 하는지 살펴보자.
public List<int[] getThem()> {
List<int[]> list1 = new ArrayList<int[]>();
for(int[] x : theList)
if(x[0] == 4)
list1.add(x);
return list1;
}복잡한 문장은 없다. 공백과 들여쓰기도 적당하다. 변수는 세개, 상수는 두 개뿐이다.
문제는 코드의 단순성이 아니라 코드의 함축성이다.
즉, 코드 맥락이 코드 자체에 명시적으로 드러나지 않는다.
- theList에 무엇이 들었는가?
- theList에서 0번째 값이 어째서 중요한가?
- 값 4는 무슨 의미인가?
- 함수가 반환하는 리스트 list1을 어떻게 사용하는가?
그렇다면 지뢰찾기 게임이라고 가정해보고 바꿔보자.
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for(int[] cell : gameBoard)
if(cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}이렇게 작성하니 이해하기 더 수월하다.
더 나아가, int 배열 대신 클래스를 사용하고, 상수 대신 isFlagged()라는 함수를 사용해 개선해보자.
public List<int[]> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<int[]>();
for(Cell cell : gameBoard)
if(cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}그릇된 정보를 피하라
- 다른 플랫폼에서 사용하는 코드를 변수이름으로 하지 말아라.
- 리스트를 000List라 명명하지 말고 000s로 명명해라.
- 서로 흡사한 이름을 사용하지 않도록 주의하라.
- l은 1과 혼동되고, O는 0과 혼동되므로 주의하라.
의미 있게 구분하라
명확한 관례가 없다면 변수 moneyAmount는 money와 구분이 안 된다.
customerInfo는 customer와, accountData는 account와, theMessage는 message와 구분이 안 된다.
읽는 사람이 차이를 알도록 이름을 지어라.발음하기 쉬운 이름을 사용하라
다른 개발자와 소통할 때 변수를 이야기하는 상황이 오게 되는데,
이때 지적인 대화가 가능해진다.
마이키, 이 레코드 좀 보세요. 'Generation Timestamp' 값이 내일 날짜입니다!나는 이 부분을 많이 반성한다…
검색하기 쉬운 이름을 사용하라
문자 하나를 사용하는 이름과 상수는 쉽게 눈에 띄지 않는다.
그래서 저자와 마찬가지로 나는 간단한 메서드에서 로컬 변수만 한 문자를 사용한다.
"이름 길이는 범위 크기에 비례해야 한다."변수나 상수를 코드 여러 곳에서 사용한다면 검색하기 쉬운 이름이어야 한다.
인코딩을 피하라
유형이나 범위 정보까지 인코딩에 넣으면 이름을 해독하기 어려워진다.
- 헝가리식 표기법 : 변수 및 함수의 인자 이름 앞에 데이터 타입을 명시하는 코딩 규칙
- 멤버 변수 접두어 : 예를 들어 멤버 변수에 m_이라는 접두어
- 인터페이스 클래스와 구현 클래스 : 구현 클래스에 인코딩( ex) ShapeFactoryImp )
자신의 기억력을 자랑하지 마라
똑똑한 프로그래머와 전문가 프로그래머 사이에서 나타나는 차이점 하나만 들자면, 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다.클래스 이름
명사나 명사구가 적합하다.
Manager, Processor, Data, Info 등과 같은 단어는 피하고, 동사는 사용하지 않는다.
매서드 이름
동사나 동사구가 적합하다.
접근자 - get, 변경자 - set, 조건자 - is
생성자를 중복정의할 때는 정적 팩토리 매서드를 사용한다.
Complex fulcrumPoint = new Complex
보다
Complex fulcrumPoint = Complex.FromRealNumber(23, 0);
가 좋다.생성자 사용을 제한하려면 해당 생성자를 private로 선언한다.
기발한 이름은 피하라
재미난 이름보다 명료한 이름을 선택하라.
농담은 피하고, 의도를 분명하고 솔직하게 표현하자.
한 개념에 한 단어를 사용하라
똑같은 매서드를 클래스마다 fetch, retrieve, get으로 제각각 부르면 혼란스럽다.
근본적으로 다르다고 생각되지 않는 것들을 통일하자.
"일관성 있는 어휘는 코드를 사용할 프로그래머가 반갑게 여길 선물이다."말장난을 하지 마라
기존 값 두 개를 더하는 개념으로 add를 사용하고 있었다가, 하나를 추가하는 개념으로 add를 사용한다면 이는 말장난이다.
inset나 append라는 이름이 적당하다.
해법 영역에서 가져온 이름을 사용하라
프로그래머에게 익숙한 기술 개념은 아주 많다.
기술 개념에는 기술 이름이 가장 적합한 선택이다. 문제 영역에서 가져온 이름을 사용하라
적절한 '프로그래머 용어'가 없다면 문제 영역에서 이름을 가져온다.의미 있는 맥락을 추가하라
‘state’ 하나만 보면 이게 뭔지 감이 오는가?
주소 일부라는 사실을 알기 위해선 ‘addrState’라는 변수를 사용하는게 적당하다.
이런 의미에서 접두어와 같은 의미있는 맥락을 추가하는 것이 좋다.
불필요한 맥락을 없애라
accountAddress와 customerAddress는 Address 클래스 인스턴스로는 좋은 이름이나
클래스 이름으로는 적합하지 못하다.마치면서
학습한 규칙 몇 개를 적용해 코드 가독성이 높아지는지 살펴야겠다.
다른 사람이 짠 코드를 손본다면 리팩터링 도구를 사용해 문제 해결 목적으로 이름을 개선하라.
우리 회사는 인텔리제이 못 쓰게 하는데…